/* 
 *  Ajax类
 *  开发：Amron
 *  日期：6-18
 */

import { AJAX_OPTIONS_DEFAULT } from "./default";
import { objToForm, spliceURL } from "./utils";
import { CONTENT_TYPE_FORM_URLENCODED, CONTENT_TYPE_JSON, HTTP_GET_REQUEST } from "./constants";

class Ajax {

  constructor(url, options) {

    this.url = url;

    this.xhr = new XMLHttpRequest();

    this.options = Object.assign({}, AJAX_OPTIONS_DEFAULT, options);

    this.init();
  }

  // 初始化各种参数
  init() {

    // 绑定各个事件
    this.bindEvents();

    // 准备发送请求
    this.xhr.open(this.options.method, spliceURL(this.url, this.options.params), true);

    // 设置响应数据类型
    this.setResponseType();

    // 设置是否传cookie
    this.setCookie();

    // 设置超时时间
    this.setTimeout();

    // 设置请求头字段
    this.setContentType();

    // 发送请求
    this.send();

  }

  bindEvents() {

    const xhr = this.xhr;
    const { success, responseError, requestError, abort, timeout } = this.options;

    // success and responseError
    xhr.addEventListener('load', () => {

      if (this.statusIsOk()) {

        success(xhr.response, xhr);
      } else {

        responseError(xhr.status, xhr)
      }

    })

    // requestError
    xhr.addEventListener('error', () => {
      requestError(xhr);
    })

    // abort
    xhr.addEventListener('abort', () => {
      abort(xhr);
    })

    // success（）
    xhr.addEventListener('timeout', () => {
      timeout(xhr);
    })

  }

  // 设置响应数据类型
  setResponseType() {
    if (this.options.responseType)
      this.xhr.responseType = this.options.responseType;
  }

  // 设置请求头字段
  setContentType() {
    if (this.options.contentType)
      this.xhr.setRequestHeader('Content-Type', this.options.contentType);
  }

  // 设置是否传cookie
  setCookie() {
    if (this.options.withCredential)
      this.xhr.withCredentials = true;
  }

  // 设置超时时间
  setTimeout() {
    if (this.options.timeoutTime > 0)
      this.xhr.timeout = this.options.timeoutTime;
  }

  // 发送请求
  send() {

    const { method, contentType, data } = this.options, xhr = this.xhr;

    let result = data;

    // 没有data或者get请求的情况
    if (method.toUpperCase() === HTTP_GET_REQUEST || data === null) return xhr.send(null);

    // 发送form表单形式的数据格式
    if (contentType.toLowerCase().includes(CONTENT_TYPE_FORM_URLENCODED)) {

      result = objToForm(result);
    }

    // 发送JSON格式的数据
    if (contentType.toLowerCase().includes(CONTENT_TYPE_JSON)) {

      result = JSON.stringify(result);
    }

    xhr.send(result);
  }

  // 判断响应是否出错
  statusIsOk() {
    return this.xhr.status >= 200 && this.xhr.status < 300 || this.xhr.status === 304
  }

}

export default Ajax;


